package com.mijie.homi.service.notify;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mijie.homi.common.constant.CategoryCode;
import com.mijie.homi.common.constant.TypeCode;
import com.mijie.homi.common.domain.SystemMessage;
import com.mijie.homi.common.domain.mood.Mood;
import com.mijie.homi.common.domain.topic.Topic;
import com.mijie.homi.common.domain.user.DeviceInfo;
import com.mijie.homi.common.domain.user.Privacy;
import com.mijie.homi.common.domain.user.User;
import com.mijie.homi.common.domain.user.UserExtInfo;
import com.mijie.homi.common.protocol.HomiProtocol;
import com.mijie.homi.common.util.HomiUtil;
import com.mijie.homi.domain.commom.Review;
import com.mijie.homi.domain.mood.MoodPushObject;
import com.mijie.homi.domain.topic.TopicOptions;
import com.mijie.homi.service.mood.MoodService;
import com.mijie.homi.service.topic.TopicService;
import com.mijie.homi.service.user.DeviceInfoService;
import com.mijie.homi.service.user.FriendService;
import com.mijie.homi.service.user.UserExtInfoService;
import com.mijie.homi.service.user.UserService;
import com.mijie.util.Helper;

@Service
public class NotifyUserAgent {

	@Autowired
	private SolicitedMessageTransporter transporter;
	@Autowired
	private FriendService friendService;
	@Autowired
	private UserService userService;
	@Autowired
	private TopicService topicService;
	@Autowired
	private UserExtInfoService userExtInfoService;
	@Autowired
	private MoodService moodService;
	@Autowired
	private DeviceInfoService deviceInfoService;
	private Logger logger = Logger.getLogger(NotifyUserAgent.class);
	
	public void sendSystemMessage(int receiver,SystemMessage msg){
		JSONObject json = JSONObject.fromObject(msg);
		json.put("createAt", msg.getCreateAt().getTime());
		HomiProtocol pack = new HomiProtocol(TypeCode.SYSTEM_MESSAGE);
		pack.setContent(json.toString());
		transporter.send(receiver, pack);
	}
	
	public void sendNotifyForTimelineEventDynamic(int receiver,int eventType,long eventId){
		HomiProtocol pack = new HomiProtocol(TypeCode.TIMELINE_DYNAMIC);
		JSONObject json = new JSONObject();
		json.accumulate("eventType", eventType);
		json.accumulate("eventId", eventId);
		pack.setContent(json.toString());
		transporter.send(receiver, pack);
	}
	
	
	public void sendNotifyForNewTopicOpinion(int opinionAuthor,int topicAuthor,int topicId,String opinion){
		if(opinionAuthor==topicAuthor) return;
		User opinionAuthorUser = userService.getUserById(opinionAuthor);
		UserExtInfo opinionAuthorExtInfo = userExtInfoService.getUserExtInfoByUserId(topicAuthor);
		DeviceInfo device = this.deviceInfoService.getDeviceInfo(opinionAuthorExtInfo.getDeviceId());
		if(device!=null && Helper.versionLessThan(device.getAppVer(), "1.0.5")){
			return;
		}
		HomiProtocol notify = new HomiProtocol(TypeCode.TOPIC_OPINION);
		JSONObject json = new JSONObject();
		json.accumulate("authorNickName", opinionAuthorUser.getNickName());
		json.accumulate("authorAvatar", HomiUtil.getRealUrl(opinionAuthorUser.getAvatar()));
		json.accumulate("authorGender", opinionAuthorUser.getGender());
		json.accumulate("authorMood", opinionAuthorExtInfo.getMood());
		json.accumulate("authorMoodUpdateAt", opinionAuthorExtInfo.getMoodUpdateAt().getTime());
		json.accumulate("author", opinionAuthorUser.getId());
		json.accumulate("topicId", topicId);
		json.accumulate("opinion", opinion);
		notify.setContent(json.toString());
		transporter.send(topicAuthor, notify);
	}
	
	public void sendNotifyForTopicVerifyPassed(Topic topic){
		UserExtInfo extInfo = userExtInfoService.getUserExtInfoByUserId(topic.getAuthor());
		DeviceInfo device = deviceInfoService.getDeviceInfo(extInfo.getDeviceId());
		if(device!=null && Helper.versionLessThan(device.getAppVer(), "1.0.5")){
			return;
		}
		HomiProtocol notify = new HomiProtocol(TypeCode.AUDIT);
		JSONObject json = new JSONObject();
		json.accumulate("category", CategoryCode.AUDIT_PASS);
		json.accumulate("topicId", topic.getId());
		json.accumulate("topicTitle", topic.getTitle());
		notify.setContent(json.toString());
		transporter.send(topic.getAuthor(), notify);
	}
	
	public void sendNotifyForTopicVerifyReject(Topic topic,List<TopicOptions> options,String reason){
		UserExtInfo extInfo = userExtInfoService.getUserExtInfoByUserId(topic.getAuthor());
		DeviceInfo device = deviceInfoService.getDeviceInfo(extInfo.getDeviceId());
		if(device!=null && Helper.versionLessThan(device.getAppVer(), "1.0.5")){
			return;
		}
		HomiProtocol notify = new HomiProtocol(TypeCode.AUDIT);
		JSONObject json = new JSONObject();
		json.accumulate("category", CategoryCode.AUDIT_REJECT);
		json.accumulate("topicId", topic.getId());
		json.accumulate("topicTitle", topic.getTitle());
		json.accumulate("topicTag", topic.getTag());
		JSONArray array = new JSONArray();
		for(TopicOptions option : options) array.add(option.getOptions());
		json.accumulate("topicOptions", array);
		json.accumulate("reason", reason);
		notify.setContent(json.toString());
		transporter.send(topic.getAuthor(), notify);
	}

	public void sendNotifyForMoodViewApply(int applicant,Mood mood){
		User applicantUser = userService.getUserById(applicant);
		UserExtInfo applicantExtInfo = userExtInfoService.getUserExtInfoByUserId(applicant) ;
		HomiProtocol notify = new HomiProtocol(TypeCode.MOOD_VIEWAPPLY);
		JSONObject json = new JSONObject();
		json.put("applicant", applicant);
		json.put("applicantNickName", applicantUser.getNickName());
		json.put("applicantAvatar", HomiUtil.getRealUrl(applicantUser.getAvatar()));
		json.put("applicantGender", applicantUser.getGender());
		json.put("applicantMood", applicantExtInfo.getMood());
		json.put("applicantMoodUpdateAt", applicantExtInfo.getMoodUpdateAt().getTime());
		json.put("moodId", mood.getId());
		json.put("moodContent", mood.getContent());
		json.put("category", CategoryCode.MOOD_VIEWAPPLY_INFO);
		notify.setContent(json.toString());
		transporter.send(mood.getUserId(), notify);
	}
	
	public void sendNotifyForAcceptMoodViewApply(int applicant,Mood mood){
		User master = userService.getUserById(mood.getUserId());
		UserExtInfo masterInfo = userExtInfoService.getUserExtInfoByUserId(mood.getUserId()) ;
		HomiProtocol notify = new HomiProtocol(TypeCode.MOOD_VIEWAPPLY);
		JSONObject json = new JSONObject();
		json.put("master", mood.getUserId());
		json.put("masterNickName", master.getNickName());
		json.put("masterAvatar", HomiUtil.getRealUrl(master.getAvatar()));
		json.put("masterGender", master.getGender());
		json.put("masterMood", masterInfo.getMood());
		json.put("masterMoodUpdateAt", masterInfo.getMoodUpdateAt().getTime());
		json.put("moodId", mood.getId());
		json.put("moodContent", mood.getContent());
		json.put("category", CategoryCode.MOOD_VIEWAPPLY_ACCEPT);
		notify.setContent(json.toString());
		transporter.send(applicant, notify);
	}
	
	public void sendNotifyForRejectMoodViewApply(int applicant,Mood mood){
		User master = userService.getUserById(mood.getUserId());
		UserExtInfo masterInfo = userExtInfoService.getUserExtInfoByUserId(mood.getUserId()) ;
		HomiProtocol notify = new HomiProtocol(TypeCode.MOOD_VIEWAPPLY);
		JSONObject json = new JSONObject();
		json.put("master", mood.getUserId());
		json.put("masterNickName", master.getNickName());
		json.put("masterAvatar", HomiUtil.getRealUrl(master.getAvatar()));
		json.put("masterGender", master.getGender());
		json.put("masterMood", masterInfo.getMood());
		json.put("masterMoodUpdateAt", masterInfo.getMoodUpdateAt().getTime());
		json.put("moodId", mood.getId());
		json.put("category", CategoryCode.MOOD_VIEWAPPLY_REJECT);
		notify.setContent(json.toString());
		transporter.send(applicant, notify);
	}
	
	public void sendNotifyForPrivacyApply(int applicant,int master,String module){
		User applicantUser = userService.getUserById(applicant);
		UserExtInfo applicantExtInfo = userExtInfoService.getUserExtInfoByUserId(applicant) ;
		String msg = null;
		if(module.equals(Privacy.MOOD_LOCUS_VISIBLE)){
			msg = " 申请查看您的心情历史";
		}
		HomiProtocol notify = new HomiProtocol(TypeCode.PRIVACY_APPLY);
		JSONObject json = new JSONObject();
		json.put("applicant", applicant);
		json.put("applicantNickName", applicantUser.getNickName());//new
		json.put("applicantAvatar", HomiUtil.getRealUrl(applicantUser.getAvatar()));//new
		json.put("applicantProvince", applicantUser.getProvince());//new
		json.put("applicantCity", applicantUser.getCity());//new
		json.put("applicantGender", applicantUser.getGender());//new
		json.put("applicantMood", applicantExtInfo.getMood());//new
		json.put("applicantMoodUpdateAt", applicantExtInfo.getMoodUpdateAt().getTime());//new
		json.put("content", applicantUser.getNickName()+msg);
		json.put("module", module);
		json.put("category", CategoryCode.PRIVACY_APPLY_INFO);//new
		notify.setContent(json.toString());
		transporter.send(master, notify);
	}
	
	public void sendNotifyForAcceptPrivacyApply(int applicant,int master,String module){
		UserExtInfo extInfo = userExtInfoService.getUserExtInfoByUserId(applicant);
		DeviceInfo device = deviceInfoService.getDeviceInfo(extInfo.getDeviceId());
		if(device!=null && Helper.versionLessThan(device.getAppVer(), "1.0.5")){
			return;
		}
		
		User masterUser = userService.getUserById(master);
		UserExtInfo masterExtInfo = userExtInfoService.getUserExtInfoByUserId(master);
		String msg = null;
		if(module.equals(Privacy.MOOD_LOCUS_VISIBLE)){
			msg = " 同意您查看"+(masterUser.getGender()==1?"他":"她")+"的心情历史";
		}
		HomiProtocol notify = new HomiProtocol(TypeCode.PRIVACY_APPLY);
		JSONObject json = new JSONObject();
		json.put("master", master);
		json.put("masterAvatar", HomiUtil.getRealUrl(masterUser.getAvatar()));
		json.put("masterNickName",masterUser.getNickName());
		json.put("masterMood", masterExtInfo.getMood());
		json.put("masterMoodUpdateAt", masterExtInfo.getMoodUpdateAt().getTime());
		json.put("content", masterUser.getNickName()+msg);
		json.put("module", module);
		json.put("category", CategoryCode.PRIVACY_APPLY_ACCEPT);
		notify.setContent(json.toString());
		transporter.send(applicant, notify);
	}
	
	public void sendNotifyForRejectPrivacyApply(int applicant,int master,String module){
		UserExtInfo extInfo = userExtInfoService.getUserExtInfoByUserId(applicant);
		DeviceInfo device = deviceInfoService.getDeviceInfo(extInfo.getDeviceId());
		if(device!=null && Helper.versionLessThan(device.getAppVer(), "1.0.5")){
			return;
		}
		User masterUser = userService.getUserById(master);
		UserExtInfo masterExtInfo = userExtInfoService.getUserExtInfoByUserId(master);
		String msg = null;
		if(module.equals(Privacy.MOOD_LOCUS_VISIBLE)){
			msg = " 拒绝您查看"+(masterUser.getGender()==1?"他":"她")+"的心情历史";
		}
		HomiProtocol notify = new HomiProtocol(TypeCode.PRIVACY_APPLY);
		JSONObject json = new JSONObject();
		json.put("master", master);
		json.put("masterNickName",masterUser.getNickName());
		json.put("masterAvatar", HomiUtil.getRealUrl(masterUser.getAvatar()));
		json.put("masterMood", masterExtInfo.getMood());
		json.put("masterMoodUpdateAt", masterExtInfo.getMoodUpdateAt().getTime());
		json.put("content", masterUser.getNickName()+msg);
		json.put("module", module);
		json.put("category", CategoryCode.PRIVACY_APPLY_REJECT);
		notify.setContent(json.toString());
		transporter.send(applicant, notify);
	}
	
	public void sendNotifyToSubscribers(final int userId){
		new Thread(){
			public void run(){
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				Set<Integer> subscribers = new HashSet<Integer>();
				subscribers.addAll(friendService.listFriendId(userId));
				subscribers.addAll(userService.listUserInfoSubcribers(userId));
				if(!subscribers.isEmpty()){
					JSONObject contentJson = userService.makeSubscribeMessage(userId);
					HomiProtocol notify = null;
					for(Integer friendId : subscribers){
						notify = new HomiProtocol(TypeCode.UPDATE_USER_INFO);
						notify.setContent(contentJson.toString());
						transporter.send(friendId,notify);
					}
				}
			}
		}.start();
	}
	
	
	public void sendNotifyToFriendForHaveNewTopic(final Topic topic){
		if(topic.getAnonymous()==1) return;
		new Thread(){
			public void run(){
				List<Integer> friends = friendService.listBeFriendWithMeUser(topic.getAuthor());
				if(!friends.isEmpty()){
					User user = userService.getUserById(topic.getAuthor());
					UserExtInfo userExtInfo = userExtInfoService.getUserExtInfoByUserId(topic.getAuthor());
					if(user==null || userExtInfo==null) return ;
					UserExtInfo extInfo = userExtInfoService.getUserExtInfoByUserId(userExtInfo.getId());
					DeviceInfo device = deviceInfoService.getDeviceInfo(extInfo.getDeviceId());
					if(device!=null && Helper.versionLessThan(device.getAppVer(), "1.0.5")){
						return;
					}
					
					JSONObject json = new JSONObject();
					json.accumulate("friendId", topic.getAuthor());
					json.accumulate("friendNickName",  user.getNickName());
					json.accumulate("friendAvatar", HomiUtil.getRealUrl(user.getAvatar()));
					json.accumulate("friendGender", user.getGender());
					json.accumulate("friendMood",userExtInfo.getMood());
					json.accumulate("friendMoodUpdateAt", userExtInfo.getMoodUpdateAt()==null?0:userExtInfo.getMoodUpdateAt().getTime());
					json.accumulate("topicId", topic.getId());
					json.accumulate("topicTitle", topic.getTitle());
					HomiProtocol notify = new HomiProtocol(TypeCode.NEW_TOPIC);
					notify.setContent(json.toString());
					for(Integer friendId : friends){
						transporter.send(friendId,notify);
					}
				}
			}
		}.start();
	}
	
	
	
	public void sendNotifyForRequestToAddFriend(int requester,int receiver){
		User user = userService.getUserById(requester);
		UserExtInfo userExtInfo = userExtInfoService.getUserExtInfoByUserId(requester);
		HomiProtocol notify = new HomiProtocol(TypeCode.FRIEND_REQUEST);
		JSONObject json = new JSONObject();
		json.accumulate("category", CategoryCode.FRIEND_REQUEST_INFO);
		json.accumulate("userId", requester);
		json.accumulate("nickName", user.getNickName());
		json.accumulate("mood", userExtInfo.getMood());
		json.accumulate("moodUpdateAt", userExtInfo.getMoodUpdateAt().getTime());
		json.accumulate("province", user.getProvince());
		json.accumulate("city", user.getCity());
		json.accumulate("gender", user.getGender());
		json.accumulate("avatar", HomiUtil.getRealUrl(user.getAvatar()));
		notify.setContent(json.toString());
		transporter.send(receiver, notify);
	}
	
	public void sendNotifyForRejectAddFriend(int userId,int requester){
		User user = userService.getUserById(userId);
		UserExtInfo userExtInfo = userExtInfoService.getUserExtInfoByUserId(requester);
		HomiProtocol notify = new HomiProtocol(TypeCode.FRIEND_REQUEST);
		JSONObject json = new JSONObject();
		json.accumulate("category", CategoryCode.FRIEND_REQUEST_REJECT);
		json.accumulate("userId", userId);
		json.accumulate("mood", userExtInfo.getMood());
		json.accumulate("moodUpdateAt", userExtInfo.getMoodUpdateAt().getTime());
		json.accumulate("gender", user.getGender());
		json.accumulate("nickName", user.getNickName());
		json.accumulate("avatar", HomiUtil.getRealUrl(user.getAvatar()));
		notify.setContent(json.toString());
		transporter.send(requester, notify);
	}
	
	public void sendNotifyForAcceptToAddFriend(int userId,int requester){
		User user = userService.getUserById(userId);
		UserExtInfo userExtInfo = userExtInfoService.getUserExtInfoByUserId(requester);
		HomiProtocol notify = new HomiProtocol(TypeCode.FRIEND_REQUEST);
		JSONObject json = new JSONObject();
		json.accumulate("category", CategoryCode.FRIEND_REQUEST_ACCEPT);
		json.accumulate("userId", userId);
		json.accumulate("mood", userExtInfo.getMood());//new
		json.accumulate("moodUpdateAt", userExtInfo.getMoodUpdateAt().getTime());//new
		json.accumulate("gender", user.getGender());
		json.accumulate("nickName", user.getNickName());
		json.accumulate("avatar", HomiUtil.getRealUrl(user.getAvatar()));
		notify.setContent(json.toString());
		transporter.send(requester, notify);
	}
	
	public void moodBroadcastNotify(MoodPushObject pushObject,int receiver){
		User moodUser = userService.getUserById(pushObject.getAuthor());
		Mood mood = moodService.getMoodById(pushObject.getMoodRecordId());
		HomiProtocol notify = new HomiProtocol(TypeCode.NEARBY_MOOD);
		JSONObject json = new JSONObject();
		json.accumulate("userId", moodUser.getId());
		json.accumulate("gender", moodUser.getGender());
		json.accumulate("mood", mood.getMood());
		json.accumulate("moodId", mood.getId());
		json.accumulate("moodContent", mood.getContent());
		json.accumulate("moodUpdateAt", mood.getCreateAt().getTime());
		json.accumulate("nickName", moodUser.getNickName());
		json.accumulate("avatar", HomiUtil.getRealUrl(moodUser.getAvatar()));
		notify.setContent(json.toString());
		transporter.send(receiver, notify);
	}
	
	public void sendReviewNotify(Review.Module module ,Review review){
		short category = 0;
		HomiProtocol notify = null;
		User author = null;
		UserExtInfo authorExtInfo = null;
		author = userService.getUserById(review.getReviewer());
		authorExtInfo = userExtInfoService.getUserExtInfoByUserId(review.getReviewer());
		if(review.getReferId()==0){
			//对应旧版的评论
			switch(module){
			case MOOD: category = CategoryCode.COMMENT_MOOD;
				break;
			case PHOTO:category = CategoryCode.COMMENT_PHOTO;
				break;
			case TOPIC_OPINION:category = CategoryCode.COMMENT_TOPIC;
				break;
			}
			JSONObject content = new JSONObject();
			content.accumulate("category", category);
			content.accumulate("targetId", review.getEventId());//兼容旧版消息中心
			content.accumulate("eventId", review.getEventId());//新版消息中心
			content.accumulate("content", review.getContent());//new
			content.accumulate("reviewer", author.getId());
			content.accumulate("reviewerNickName", author.getNickName());
			content.accumulate("reviewerAvatar", HomiUtil.getRealUrl(author.getAvatar()));
			content.accumulate("reviewerMood", authorExtInfo.getMood());
			content.accumulate("reviewerMoodUpdateAt", authorExtInfo.getMoodUpdateAt().getTime());
			notify = new HomiProtocol(TypeCode.COMMENT);
			notify.setContent(content.toString());
		}else{
			switch(module){
			case MOOD: 
				category = CategoryCode.REPLY_MOOD;
				break;
			case PHOTO:
				category = CategoryCode.REPLY_PHOTO;
				break;
			case TOPIC_OPINION:
				category = CategoryCode.REPLY_TOPIC;
				break;
			}
			JSONObject content = new JSONObject();
			content.accumulate("category", category);
			content.accumulate("referId", review.getReferId()); //新版消息中心
			content.accumulate("parentId", review.getParentId()); //兼容旧版消息中心
			content.accumulate("targetId", review.getEventId());//兼容旧版消息中心
			content.accumulate("eventId", review.getEventId());//新版消息中心
			content.accumulate("content", review.getContent());// new
			content.accumulate("reviewer", author.getId());
			content.accumulate("reviewerNickName", author.getNickName());
			content.accumulate("reviewerAvatar", HomiUtil.getRealUrl(author.getAvatar()));
			content.accumulate("reviewerMood", authorExtInfo.getMood());
			content.accumulate("reviewerMoodUpdateAt", authorExtInfo.getMoodUpdateAt().getTime());
			notify = new HomiProtocol(TypeCode.REPLY);
			notify.setContent(content.toString());
		}
		
		transporter.send(review.getReceiver(),notify);
	}
}
